#!/bin/bash

# 资产管理系统 - 数据备份脚本
# 版本: 1.0

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 配置变量
APP_DIR="/opt/asset-management"
BACKUP_DIR="/opt/asset_backups"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查环境
check_environment() {
    if [[ ! -d "$APP_DIR" ]]; then
        log_error "应用目录不存在: $APP_DIR"
        exit 1
    fi
    
    if [[ ! -f "$APP_DIR/.env" ]]; then
        log_error "环境配置文件不存在: $APP_DIR/.env"
        exit 1
    fi
    
    cd "$APP_DIR"
}

# 创建备份目录
create_backup_dir() {
    mkdir -p "$BACKUP_DIR/$DATE"
    log_info "创建备份目录: $BACKUP_DIR/$DATE"
}

# 备份数据库
backup_database() {
    log_info "开始备份数据库..."
    
    # 备份数据库
    docker-compose exec -T db mysqldump \
        -u root \
        -p123456 \
        --single-transaction \
        --routines \
        --triggers \
        asset_db > "$BACKUP_DIR/$DATE/database.sql"
    
    # 压缩数据库备份
    gzip "$BACKUP_DIR/$DATE/database.sql"
    
    log_success "数据库备份完成"
}

# 备份媒体文件
backup_media() {
    log_info "开始备份媒体文件..."
    
    # 备份媒体文件
    docker cp asset_web:/app/media "$BACKUP_DIR/$DATE/"
    
    # 备份静态文件
    docker cp asset_web:/app/static "$BACKUP_DIR/$DATE/"
    
    log_success "媒体文件备份完成"
}

# 备份配置文件
backup_config() {
    log_info "开始备份配置文件..."
    
    # 备份环境配置
    cp .env "$BACKUP_DIR/$DATE/"
    
    # 备份Docker配置
    cp -r docker "$BACKUP_DIR/$DATE/"
    
    # 备份docker-compose文件
    cp docker-compose.yml "$BACKUP_DIR/$DATE/"
    
    log_success "配置文件备份完成"
}

# 创建备份信息文件
create_backup_info() {
    log_info "创建备份信息文件..."
    
    cat > "$BACKUP_DIR/$DATE/backup_info.txt" << EOF
备份信息
========
备份时间: $(date)
备份类型: 完整备份
数据库版本: $(docker-compose exec -T db mysql --version)
应用版本: $(docker-compose exec -T web python manage.py version 2>/dev/null || echo "未知")

包含内容:
- 数据库: database.sql.gz
- 媒体文件: media/
- 静态文件: static/
- 配置文件: .env, docker-compose.yml, docker/

备份大小: $(du -sh "$BACKUP_DIR/$DATE" | cut -f1)
EOF
    
    log_success "备份信息文件创建完成"
}

# 压缩备份
compress_backup() {
    log_info "压缩备份文件..."
    
    cd "$BACKUP_DIR"
    tar -czf "backup_$DATE.tar.gz" "$DATE"
    
    # 删除临时目录
    rm -rf "$DATE"
    
    local backup_size=$(du -sh "backup_$DATE.tar.gz" | cut -f1)
    log_success "备份压缩完成，大小: $backup_size"
}

# 清理旧备份
cleanup_old_backups() {
    log_info "清理旧备份文件..."
    
    local deleted_count=0
    
    # 删除超过保留期的备份
    while IFS= read -r -d '' file; do
        rm -f "$file"
        ((deleted_count++))
        log_info "删除旧备份: $(basename "$file")"
    done < <(find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +$RETENTION_DAYS -print0)
    
    if [[ $deleted_count -eq 0 ]]; then
        log_info "没有需要清理的旧备份"
    else
        log_success "清理了 $deleted_count 个旧备份文件"
    fi
}

# 验证备份
verify_backup() {
    log_info "验证备份文件..."
    
    local backup_file="$BACKUP_DIR/backup_$DATE.tar.gz"
    
    if [[ -f "$backup_file" ]]; then
        # 测试压缩文件完整性
        if tar -tzf "$backup_file" >/dev/null 2>&1; then
            log_success "备份文件验证通过"
        else
            log_error "备份文件损坏"
            exit 1
        fi
    else
        log_error "备份文件不存在"
        exit 1
    fi
}

# 发送通知（可选）
send_notification() {
    local backup_file="$BACKUP_DIR/backup_$DATE.tar.gz"
    local backup_size=$(du -sh "$backup_file" | cut -f1)
    
    # 这里可以添加邮件或其他通知方式
    log_info "备份完成通知:"
    log_info "  文件: $backup_file"
    log_info "  大小: $backup_size"
    log_info "  时间: $(date)"
}

# 主函数
main() {
    log_info "开始执行数据备份..."
    log_info "备份时间: $(date)"
    
    check_environment
    create_backup_dir
    backup_database
    backup_media
    backup_config
    create_backup_info
    compress_backup
    cleanup_old_backups
    verify_backup
    send_notification
    
    log_success "数据备份完成！"
    log_info "备份文件: $BACKUP_DIR/backup_$DATE.tar.gz"
}

# 执行主函数
main "$@"